//
//  MoNavigationController.swift
//  soapp-docoment
//
//  Created by zhu xietong on 2022/12/29.
//

import Foundation
import UIKit
import soapp
import Eelay


extension UINavigationController{    
    static private var hasSwizzing = false
    static func doSwizzing(){
        if hasSwizzing{
            return
        }
        hasSwizzing = true
        
        DispatchQueue.once(token: "onceToken")
        {
            let needSwizzleSelectorArr = [
                NSSelectorFromString("_updateInteractiveTransition:"),
            ]
            for selector in needSwizzleSelectorArr {
                let str = ("mo_" + selector.description).replacingOccurrences(of: "__", with: "_")
                if let originalMethod = class_getInstanceMethod(self, selector),
                    let swizzledMethod = class_getInstanceMethod(self, Selector(str)) {
                    method_exchangeImplementations(originalMethod, swizzledMethod)
                }
            }
        }
    }
    
    
    @objc func mo_updateInteractiveTransition(_ percentComplete: CGFloat) {
        self.mo_updateInteractiveTransition(percentComplete)
    }

   
}
class MoNavigationController:UINavigationController,UINavigationBarDelegate,UINavigationControllerDelegate{
    
    
    var sampleNum:Int = 5
    override func mo_updateInteractiveTransition(_ percentComplete: CGFloat) {
        super.mo_updateInteractiveTransition(percentComplete)
        guard let topViewController = topViewController, let coordinator = topViewController.transitionCoordinator else {
            mo_updateInteractiveTransition(percentComplete)
            return
        }
        
        
        sampleNum = sampleNum + 1
        if sampleNum % 6 == 0{
            sampleNum = 0
            let fromViewController = coordinator.viewController(forKey: .from)
            let toViewController = coordinator.viewController(forKey: .to)
            let fromStyle = fromViewController?.top_style ?? EeTopStyle.default
            let toStyle = toViewController?.top_style ?? EeTopStyle.default
            let fromColor = fromStyle.navTintColor
            let toColor = toStyle.navTintColor
            let newColor = UIColor.averageColor(fromColor: fromColor, toColor: toColor, percent: percentComplete)
            navigationBar.tintColor = newColor
            navigationBar.titleTextAttributes = [.foregroundColor:newColor]
        }
        
    }
    var popDelegate: UIGestureRecognizerDelegate? = nil
    override init(rootViewController: UIViewController) {
        
        UINavigationController.doSwizzing()
        super.init(navigationBarClass: MoNavigaionBar.self, toolbarClass: nil)
        self.viewControllers = [rootViewController]
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func viewDidLoad() {
        self.delegate = self
        super.viewDidLoad()
        self.popDelegate = self.interactivePopGestureRecognizer?.delegate
        _ = viewControllers.first?.extentionNavigationBar(navigationController: self)
        
    }
    
    override var preferredStatusBarStyle: UIStatusBarStyle{
        return topViewController?.top_style.statusBarStyle ?? .default
    }

 
    override func popViewController(animated: Bool) -> UIViewController? {
        let ctr = super.popViewController(animated: animated)
        weak var wself = self
        if animated{
            UIView.animate(withDuration: 0.2) {[weak self] in
                if let top = wself?.topViewController{
                    wself?.navigationBar.tintColor = top.top_style.navTintColor
                }
            } completion: { f in
                
            }
        }else{
            if let top = topViewController{
                navigationBar.tintColor = top.top_style.navTintColor
            }
        }
        return ctr
    }
    
    
    func navigationLeftItemClickPop(owner:UIViewController?){
        self.popViewController(animated: true)
    }
    
    func navigationBar(_ navigationBar: UINavigationBar, shouldPush item: UINavigationItem) -> Bool {
        return true
    }
    
    func navigationBar(_ navigationBar: UINavigationBar, shouldPop item: UINavigationItem) -> Bool {
        print("----shouldPop",topViewController)

        if let coordinator = topViewController?.transitionCoordinator{
            print("----llllss",coordinator)
        }
        return true
    }

    
    // deal the gesture of return break off
    private func dealInteractionChanges(_ context: UIViewControllerTransitionCoordinatorContext)
    {
        
        weak var wself = self
        let animations: (UITransitionContextViewControllerKey) -> () = {
            let style:EeTopStyle = context.viewController(forKey: $0)?.top_style ?? .default
            let curColor = style.navTintColor
     
            wself?.navigationBar.tintColor = style.navTintColor
            wself?.navigationBar.titleTextAttributes = style.titleTextAttributes

        }
        
        if context.isCancelled
        {
            let cancelDuration: TimeInterval = context.transitionDuration * Double(context.percentComplete)
            UIView.animate(withDuration: cancelDuration) {
                animations(.from)
            }
        }
        else
        {
            // after that, finish the gesture of return
            let finishDuration: TimeInterval = context.transitionDuration * Double(1 - context.percentComplete)
            UIView.animate(withDuration: finishDuration) {
                animations(.to)
            }
        }
    }
    
    
    
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        
        
        viewController.extentionNavigationBar(navigationController: navigationController)
//        navigationController.navigationBar.tintColor = viewController.top_style.navTintColor

        navigationController.navigationBar.titleTextAttributes = viewController.top_style.titleTextAttributes
        navigationController.setNeedsStatusBarAppearanceUpdate()
        guard let coor = viewController.transitionCoordinator else {
            return
        }
         coor.notifyWhenInteractionChanges({ (context) in
             print("will-notifyWhenInteractionChanges",context)
             self.dealInteractionChanges(context)
         })
        coor.notifyWhenInteractionChanges({ (context) in
            print("will-end",context)
            self.dealInteractionChanges(context)
        })
         

    }
    
   
    
    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        if viewController == self.viewControllers.first {
            self.interactivePopGestureRecognizer?.delegate = self.popDelegate
        }else{
            self.interactivePopGestureRecognizer?.delegate = nil
        }
        viewController.view.clipsToBounds = false
        navigationController.navigationBar.tintColor = viewController.top_style.navTintColor
        navigationController.navigationBar.titleTextAttributes = viewController.top_style.titleTextAttributes
        navigationController.setNeedsStatusBarAppearanceUpdate()

    }
    
    
   
}


extension UIViewController{
    private struct __extention_NavgaitionBar {
        static var base = "__extention_NavgaitionBar"
    }
    
    @discardableResult
    func extentionNavigationBar(navigationController:UINavigationController)->NavigationBar{
        
        if let bar = objc_getAssociatedObject(self, &__extention_NavgaitionBar.base) as? NavigationBar
        {
            bar.navigaionController = navigationController
            return bar
        }
        else
        {
            let bar = NavigationBar(navigaionController: navigationController)
            bar.owerController = self
            objc_setAssociatedObject(self, &__extention_NavgaitionBar.base, bar, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            return bar
        }
    }
    
    class NavigationBar:UIView{
        weak var navigaionController:UINavigationController? = nil
        weak var owerController:UIViewController? = nil{
            didSet{
                guard let nav = navigaionController,let owner = owerController else{ return }
                
                if owner.navigationItem.leftBarButtonItem == nil{
                    owner.navigationItem.leftBarButtonItem = UIBarButtonItem(image: UIImage(_snamed: "page_back_indicator"), style: .plain, target: self, action: #selector(leftBarButtonItemClick))
                }
                let frame = nav.navigationBar.frame
                owner.view.clipsToBounds = false
                self.frame = [0,TP.topLayoutGuide,frame.width,frame.height]
                owner.view.addSubview(self)
                switch top_style.navBarBgStyle{
                case .color(let color):
                    backgroundView.backgroundColor = color
                default:
                    break
                }
                backgroundView.alpha = top_style.navBarBgAlpha
            }
        }
        
        @objc func leftBarButtonItemClick(){
            (navigaionController as? MoNavigationController)?.navigationLeftItemClickPop(owner: owerController)
        }

        let titleLabel = UILabel()
        let backgroundView = UIView()
        var top_style:EeTopStyle{
            set{
                switch newValue.navBarBgStyle{
                case .color(let color):
                    backgroundView.backgroundColor = color
                default:
                    break
                }
                backgroundView.alpha = newValue.navBarBgAlpha
            }
            get{
                return owerController?.top_style ?? EeTopStyle.default
            }
        }
        
        init(navigaionController:UINavigationController) {
            self.navigaionController = navigaionController
            super.init(frame: .zero)
            loadView()
        }
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
            loadView()
        }
        
        func loadView(){
            clipsToBounds = false
            layer.zPosition = 100
            eelay = [
                [backgroundView,[ee.L.B.R],[ee.T,-TP.topLayoutGuide]]
            ]
            
        }
    }
}


extension MoNavigationController{
    
    
    
    open class MoNavigaionBar:UINavigationBar{
        
        open override var tintColor: UIColor?{
            get{
                return super.tintColor
            }
            set{
                super.tintColor = newValue
                print("MoNavigaionBar.tintColor.set",newValue)
            }
        }
                
        public override init(frame: CGRect) {
            super.init(frame: frame)
   
        }
        
        init(){
            super.init(frame: .zero)
     
        }
        
        required public init?(coder: NSCoder) {
            super.init(coder: coder)
         
        }
//        open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
//            return nil
//        }
        
        open override func draw(_ rect: CGRect) {
//            super.draw(rect)
        }
    }
    
}
